/**
 * File: PositionReadController.java
 * Created by: mhaimel
 * Created on: 22 Jul 2009
 * CVS:  $Id: PositionReadController.java,v 1.3 2009/11/24 16:31:20 mhaimel Exp $
 */
package uk.ac.ebi.curtain.controller.loader;

import java.io.File;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Future;

import uk.ac.ebi.curtain.controller.ParallelSingleSubmitController;
import uk.ac.ebi.curtain.controller.SimpleReport;
import uk.ac.ebi.curtain.controller.loader.impl.ReadsWriteBean;
import uk.ac.ebi.curtain.management.IControllerReport;
import uk.ac.ebi.curtain.processor.load.impl.PositionReadProcessor;
import uk.ac.ebi.curtain.processor.writer.BucketCollectionBean;
import uk.ac.ebi.curtain.utils.data.ReadType;

/**
 * @author mhaimel
 *
 */
public class PositionReadController extends ParallelSingleSubmitController<BucketCollectionBean, Serializable, PositionReadProcessor> {

	private volatile PositionReadProcessor paired_reader;
	private volatile PositionReadProcessor unpaired_reader;

	@Override
	protected void singleSubmit(List<BucketCollectionBean> inputList) {
		getLog().info("Processing " + inputList.size() + " buckets ... ");
		for(ReadType rt : ReadType.getPaired()){
			File pairedReadFile = getContext().currentFiles().getEntryFilePosition(rt);
			if(pairedReadFile.exists()){
				paired_reader = getContext().getInjector().getInstance(PositionReadProcessor.class);
				paired_reader.setPositionSize(2);
				paired_reader.addFile(pairedReadFile);
				for(BucketCollectionBean bean : inputList){
					paired_reader.register(bean.getPaired_reads());
				}
				submit(paired_reader);
			}else {
				getLog().info("No " + rt + " position information available to add!");
			}
		}

		for(ReadType rt : ReadType.getUnpaired()){
			File unpairedReadFile = getContext().currentFiles().getEntryFilePosition(rt);
			if(unpairedReadFile.exists()){
				unpaired_reader = getContext().getInjector().getInstance(PositionReadProcessor.class);
				unpaired_reader.setPositionSize(1);
				unpaired_reader.addFile(unpairedReadFile);
		//				new File(getContext().currentFiles().getWorkingDir(),"file_unpaired_entry_position.xf.gz"));
				for(BucketCollectionBean bean : inputList){
					unpaired_reader.register(bean.getUnpaired_reads());
				}
				submit(unpaired_reader);
			} else {
				getLog().info("No " + rt + " position information available to add!");
			}
		}
	}

	@Override
	protected IControllerReport getReturnCall() {
		return new SimpleReport("Finished");
	}
	
	@Override
	protected void processResult(Future<Serializable> res,PositionReadProcessor job) {
		extractResult(res, job);
		// don't to anything
	}
	
	@Override
	protected void doShutdown() {
		_processResults();
		super.doShutdown();
	}

	private void _processResults() {
		Collection<BucketCollectionBean> beanList = getInputList();
		for(BucketCollectionBean bean : beanList){
			ReadsWriteBean writer = new ReadsWriteBean();
			writer.setBaseDir(bean.getBaseDir());
			if(null != paired_reader){
				addReadPos(bean.getPaired_reads(), paired_reader, writer);
			}
			if(null != unpaired_reader){
				addReadPos(bean.getUnpaired_reads(), unpaired_reader, writer);
			}
			interceptorHandle(writer);		
			bean.setPaired_reads((Set<String>) Collections.EMPTY_SET);
			bean.setUnpaired_reads((Set<String>) Collections.EMPTY_SET);
			bean.setContigs((Set<String>) Collections.EMPTY_SET);
		}
		if(null != paired_reader){
			paired_reader.reset();
			paired_reader = null;
		}
		if(null != unpaired_reader){
			unpaired_reader.reset();
			unpaired_reader = null;
		}
		setInputList((List<BucketCollectionBean>) Collections.EMPTY_LIST);
	}

	private void addReadPos(Set<String> set, PositionReadProcessor reader, ReadsWriteBean writer) {
		for(String read : set){
			Long[] posArr = reader.pos4Read(read);
			for(Long pos : posArr){
				if(pos >= 0){
					writer.addReadPosition(pos);
				}
			}
		}
	}

}
